/**
 * JWT工具模块
 * 提供JWT令牌的生成、验证和刷新功能
 */

import jwt from 'jsonwebtoken';
import { config } from '../config/index.js';

/**
 * 生成JWT令牌
 * @param {Object} payload - 令牌载荷数据（通常包含用户ID和用户名）
 * @param {Object} options - JWT选项（可选）
 * @returns {string} 生成的JWT令牌
 * @throws {Error} 当JWT_SECRET未配置或payload无效时抛出错误
 */
export const generateToken = (payload, options = {}) => {
  // 参数验证
  if (!payload || typeof payload !== 'object') {
    throw new Error('Token payload must be a valid object');
  }

  if (!config.jwt.secret) {
    throw new Error('JWT_SECRET is not configured');
  }

  // 默认选项
  const defaultOptions = {
    expiresIn: config.jwt.expiresIn || '7d', // 默认7天过期
  };

  // 合并选项
  const finalOptions = { ...defaultOptions, ...options };

  try {
    // 生成令牌
    const token = jwt.sign(payload, config.jwt.secret, finalOptions);
    return token;
  } catch (error) {
    throw new Error(`Failed to generate token: ${error.message}`);
  }
};

/**
 * 验证JWT令牌
 * @param {string} token - 要验证的JWT令牌
 * @returns {Object} 解码后的令牌载荷
 * @throws {Error} 当令牌无效、过期或格式错误时抛出错误
 */
export const verifyToken = (token) => {
  // 参数验证
  if (!token || typeof token !== 'string') {
    throw new Error('Token must be a valid string');
  }

  if (!config.jwt.secret) {
    throw new Error('JWT_SECRET is not configured');
  }

  try {
    // 验证并解码令牌
    const decoded = jwt.verify(token, config.jwt.secret);
    return decoded;
  } catch (error) {
    // 处理不同的错误类型
    if (error.name === 'TokenExpiredError') {
      throw new Error('TOKEN_EXPIRED');
    } else if (error.name === 'JsonWebTokenError') {
      throw new Error('INVALID_TOKEN');
    } else {
      throw new Error(`Token verification failed: ${error.message}`);
    }
  }
};

/**
 * 刷新JWT令牌
 * 验证旧令牌，如果有效则使用相同载荷生成新令牌
 * @param {string} token - 要刷新的JWT令牌
 * @param {Object} options - 新令牌的选项（可选）
 * @returns {string} 新生成的JWT令牌
 * @throws {Error} 当令牌无效或过期时抛出错误
 */
export const refreshToken = (token, options = {}) => {
  try {
    // 验证旧令牌（忽略过期时间）
    const decoded = jwt.verify(token, config.jwt.secret, {
      ignoreExpiration: true,
    });

    // 从解码的令牌中提取载荷（移除JWT内部字段）
    const { iat, exp, ...payload } = decoded;

    // 生成新令牌
    return generateToken(payload, options);
  } catch (error) {
    if (error.message === 'INVALID_TOKEN') {
      throw error;
    }
    throw new Error(`Failed to refresh token: ${error.message}`);
  }
};

/**
 * 解码JWT令牌（不验证签名）
 * 仅用于调试或获取令牌信息，不应用于安全验证
 * @param {string} token - JWT令牌
 * @returns {Object|null} 解码后的令牌载荷，失败返回null
 */
export const decodeToken = (token) => {
  try {
    return jwt.decode(token);
  } catch (error) {
    return null;
  }
};

export default {
  generateToken,
  verifyToken,
  refreshToken,
  decodeToken,
};

